package conversions

import (
	"jvm/instructions/base"
	"jvm/rtda"
	. "jvm/typedef"
)

// 弹出栈顶元素，将其转化为其他类型后入栈(不需操作数)

// *****************************************************************
// 栈顶int元素弹出，转成byte型后入栈
type I2B struct {
	base.NoOperandsInst
}

func (self *I2B) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	i := stack.PopInt()
	b := I1(i)
	stack.PushInt(I4(b))
}

// *****************************************************************
// 栈顶int元素弹出，转成char型后入栈
type I2C struct {
	base.NoOperandsInst
}

func (self *I2C) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	i := stack.PopInt()
	c := U2(i)
	stack.PushInt(I4(c))
}

// *****************************************************************
// 栈顶int元素弹出，转成short型后入栈
type I2S struct {
	base.NoOperandsInst
}

func (self *I2S) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	i := stack.PopInt()
	s := I2(i)
	stack.PushInt(I4(s))
}

// *****************************************************************

// 栈顶int元素弹出，转成long型后入栈
type I2L struct {
	base.NoOperandsInst
}

func (self *I2L) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	i := stack.PopInt()
	stack.PushLong(I8(i))

}

// *****************************************************************
type I2F struct {
	base.NoOperandsInst
}

func (self *I2F) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	i := stack.PopInt()
	stack.PushFloat(F4(i))

}

// *****************************************************************
type I2D struct {
	base.NoOperandsInst
}

func (self *I2D) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	i := stack.PopInt()
	stack.PushDouble(F8(i))

}

// *****************************************************************
// 栈顶long元素弹出，转成int型后入栈
type L2I struct {
	base.NoOperandsInst
}

func (self *L2I) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	l := stack.PopLong()
	stack.PushInt(I4(l))

}

// *****************************************************************
type L2F struct {
	base.NoOperandsInst
}

func (self *L2F) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	l := stack.PopLong()
	stack.PushFloat(F4(l))

}

// *****************************************************************
type L2D struct {
	base.NoOperandsInst
}

func (self *L2D) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	l := stack.PopLong()
	stack.PushDouble(F8(l))

}

// *****************************************************************
// 栈顶float元素弹出，转成int型后入栈
type F2I struct {
	base.NoOperandsInst
}

func (self *F2I) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	f := stack.PopFloat()
	stack.PushInt(I4(f))

}

// *****************************************************************
type F2L struct {
	base.NoOperandsInst
}

func (self *F2L) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	f := stack.PopFloat()
	stack.PushLong(I8(f))

}

// *****************************************************************
type F2D struct {
	base.NoOperandsInst
}

func (self *F2D) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	f := stack.PopFloat()
	stack.PushDouble(F8(f))

}

// *****************************************************************

// 栈顶double元素弹出，转成int型后入栈
type D2I struct {
	base.NoOperandsInst
}

func (self *D2I) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	d := stack.PopDouble()
	stack.PushInt(I4(d))

}

// *****************************************************************
type D2L struct {
	base.NoOperandsInst
}

func (self *D2L) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	d := stack.PopDouble()
	stack.PushLong(I8(d))

}

// *****************************************************************
type D2F struct {
	base.NoOperandsInst
}

func (self *D2F) Execute(frame *rtda.Frame) {
	stack := frame.OPStack()
	d := stack.PopDouble()
	stack.PushFloat(F4(d))

}
